<?php
/* 短信模块主类 */
class Sms {

    var $sms_name = 'dlkltzf1';           //用户名
    var $sms_password = 'ZDJwZA63';      //密码
    var $sms_auth_str = '【连心卡】';  //短信签名

    private $api_type = '';
    private $sms_url = "http://cf.51welink.com/submitdata/Service.asmx/g_Submit";

    function __construct() {
    	$this->CI = & get_instance();
    	$this->CI->load->library("Apilog");
    	$this->apilog = $this->CI->apilog;
    }
    //发送单个短消息
    function sendSingle($phones, $msg, $user_id = 0){
        if (empty($phones) || empty($msg)) {
            return false;
        }
        $msg .= $this->sms_auth_str;    //添加   签名格式
        $post_data = "sname=" . $this->sms_name .
            "&spwd=" . $this->sms_password .
            "&scorpid=&sprdid=1012888" .
            "&sdst=" . $phones .
            "&smsg=" .rawurlencode($msg);
        $rqtimestamp = time();
        $get = $this->Post($post_data, $this->sms_url);
        $gets = $this->xml_to_array($get);
        $rptimestamp = time();
        $msg = $gets['CSubmitState']['MsgState'];
        if(empty($gets)){
        	$msg = '通信失败';
        }
        $this->writelog(101, $post_data, $get, $msg, $rqtimestamp, $rptimestamp, substr($phones,0,11),$user_id);
        if ($gets['CSubmitState']['State'] == 0) {
            return true;
        } else {
            //$this->logResult($gets['CSubmitState']['MsgState'], $gets['CSubmitState']['State'], $get, 2);
            return false;
        }
    }
    // 发送短消息
    function send($phones, $msg ,$user_id) {

        /* 检查发送信息的合法性 */
        $contents = $this->get_contents($phones, $msg);
        if (!$contents) {
            return false;
        }

        /* 获取API URL */
        $count = count($contents);
        $rqtimestamp = time();
        foreach ($contents as $key => $val) {
            $post_data = "sname=" . $this->sms_name . 
                         "&spwd=" . $this->sms_password . 
                         "&scorpid=&sprdid=1012888" . 
                         "&sdst=" . $val['phones'] .
                         "&smsg=" .rawurlencode($val['content']);
            $get = $this->Post($post_data, $this->sms_url);
            $gets = $this->xml_to_array($get);
            $rptimestamp = time();
            $this->writelog(101, $post_data, $get, $gets['CSubmitState']['MsgState'], $rqtimestamp, $rptimestamp, 0,$user_id);
            if ($gets['CSubmitState']['State'] != 0 || empty($gets)){
            	$flag = false;
            }
            if($count > 1)
            {
                sleep(1);
            }
        }
        
        if ($flag) {
            return true;
        } else {
            return false;
        }
    }

    private function Post($data, $target) {
        $url_info = parse_url($target);
        $httpheader = "POST " . $url_info['path'] . " HTTP/1.0\r\n";
        $httpheader .= "Host:" . $url_info['host'] . "\r\n";
        $httpheader .= "Content-Type:application/x-www-form-urlencoded\r\n";
        $httpheader .= "Content-Length:" . strlen($data) . "\r\n";
        $httpheader .= "Connection:close\r\n\r\n";
        //$httpheader .= "Connection:Keep-Alive\r\n\r\n";
        $httpheader .= $data;

        $this->api_type = 'POST';
        $fd = fsockopen($url_info['host'], 80, $errno, $errstr, 30);
        if( !$fd ) {                          //如果打开出错
            $n_url_info = parse_url('http://zf.51welink.com/submitdata/service.asmx');
            $fd = fsockopen($n_url_info['host'], 80, $errno, $errstr, 30);
            if( !$fd ){
                //看看要不要发邮件通知
                exit(json_encode(array('code' => 1,'msg' => '发送验证码失败！')));
            }
        }
        fwrite($fd, $httpheader);
        $gets = "";
        while(!feof($fd)) {
            $gets .= fread($fd, 128);
        }
        fclose($fd);
        if($gets != ''){
            $start = strpos($gets, '<?xml');
            if($start > 0) {
                $gets = substr($gets, $start);
            }
        }
        return $gets;
    }

    private function xml_to_array($xml) {
        $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*)<\\/\\1>/";
        if (preg_match_all($reg, $xml, $matches)) {
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i++) {
                $subxml = $matches[2][$i];
                $key = $matches[1][$i];
                if (preg_match($reg, $subxml)) {
                    $arr[$key] = $this->xml_to_array($subxml);
                } else {
                    $arr[$key] = $subxml;
                }
            }
        }
        return $arr;
    }

    //检查手机号和发送的内容并生成生成短信队列
    private function get_contents($phones, $msg) {
        if (empty($phones) || empty($msg)) {
            return false;
        }

        $msg .= $this->sms_auth_str;

        if (EC_CHARSET != 'utf-8') {
            $msg = $this->auto_charset($msg);
        }

        $phone_key = 0;
        $i = 0;
        $phones = explode(',', $phones);
        foreach ($phones as $key => $value) {
            if ($i < 200) {
                $i++;
            } else {
                $i = 0;
                $phone_key++;
            }
            if ($this->is_moblie($value)) {
                $phone[$phone_key][] = $value;
            } else {
                $i--;
            }
        }
        if (!empty($phone)) {
            foreach ($phone as $phone_key => $val) {
                $phone_array[$phone_key]['phones'] = implode(',', $val);
                $phone_array[$phone_key]['content'] = $msg;
            }
            return $phone_array;
        } else {
            return false;
        }
    }

    // 自动转换字符集 支持数组转换
    private function auto_charset($fContents, $from = 'gbk', $to = 'utf-8') {
        $from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
        $to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
        if (strtoupper($from) === strtoupper($to) || empty($fContents) || (is_scalar($fContents) && !is_string($fContents))) {
            //如果编码相同或者非字符串标量则不转换
            return $fContents;
        }
        if (is_string($fContents)) {
            if (function_exists('mb_convert_encoding')) {
                return mb_convert_encoding($fContents, $to, $from);
            } elseif (function_exists('iconv')) {
                return iconv($from, $to, $fContents);
            } else {
                return $fContents;
            }
        } elseif (is_array($fContents)) {
            foreach ($fContents as $key => $val) {
                $_key = $this->auto_charset($key, $from, $to);
                $fContents[$_key] = $this->auto_charset($val, $from, $to);
                if ($key != $_key)
                    unset($fContents[$key]);
            }
            return $fContents;
        }
        else {
            return $fContents;
        }
    }

    // 检测手机号码是否正确
    private function is_moblie($moblie) {
        return preg_match("/^1[3|4|5|7|8][0-9]\d{8}$/", $moblie);
    }

    //打印日志
    private function logResult($api_msg = '', $api_code = '', $api_data = '', $api_status = 0) {
        $data['user_id'] = I('session.user_id', 0, 'intval');
        $data['api_url'] = $this->sms_url;
        $data['api_method'] = $this->sms_url;
        $data['api_data'] = $api_data;
        $data['api_date'] = NOW_TIME;
        $data['api_type'] = $this->api_type;
        $data['api_code'] = $api_code;
        $data['api_msg'] = $api_msg;
        $data['api_status'] = $api_status;
        $data['api_cardtype'] = 2;
        if ( $api_status == 1 ){
            $data['api_code'] = 01;
            $data['api_msg'] = '准备发送';
        }elseif( $api_status == 2 ){
            $data['api_code'] = 00;
            $data['api_msg'] = '发送失败';
        }
        $keys = array_keys($data);
        $values = array_values($data);
        $sql = "INSERT INTO " . C('DB.DB_PREFIX') ."api_log (`" . implode('`,`', $keys). "`) VALUES('" . implode("','", $values). "')";
        model('Base')->model->query($sql);
    }
    /**
     * 日志记录方法
     * @param $type请求类型代码
     * @param $request请求数据
     * @param $response响应数据
     * @param $msg描述信息
     * @param $rqtimestamp请求时间戳
     * @param $rptimestamp响应时间戳
     * @param $orderid订单号
     * @param $uid发起请求用户的userid
     * @return null
     * @author moon 2017.08.08
     */
    private function writelog($type,$request,$response,$msg,$rqtimestamp,$rptimestamp,$orderid = 0,$uid = 0){
    	if(is_array($request))
    		$request = $this->json_my_encode($request);
    		if(is_array($response))
    			$response = $this->json_my_encode($response);
    			$this->apilog->addlog($type,$rqtimestamp,$rptimestamp,$uid,$orderid,$msg,$request,$response);
    }
    
    /**
     * 自定义$this->json_my_encode函数
     * @param $data array
     * @return json string
     * @author moon 2017.08.08
     */
    private function json_my_encode($data){
    	$str = json_encode( $data);
    	$str =  preg_replace_callback(
    			"#\\\u([0-9a-f]{4})#i",
    			function( $matchs)
    			{
    				return  iconv('UCS-2BE', 'UTF-8',  pack('H4',  $matchs[1]));
    	},
    	$str
    	);
    	return  $str;
    }
}

?>